package com.youan.log.modules.audit.dataimport;

import com.youan.log.common.bean.ValidateResult;
import com.youan.log.modules.audit.dataimport.bean.DataFile;
import com.youan.log.modules.audit.dataimport.bean.TaskData;
import com.youan.log.modules.audit.entity.ImportRecord;
import com.youan.log.modules.audit.service.IImportRecordService;
import org.apache.commons.lang.time.DateFormatUtils;
import org.springblade.common.cache.ParamCache;
import org.springblade.core.log.exception.ServiceException;
import org.springblade.core.tool.utils.SpringUtil;

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.LineNumberReader;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 从导入数据文件夹获取导入任务数据
 * @author xsh
 * @date 2021/3/5 9:13
 */
public class TaskDataGetter {

    public TaskData getTaskData(String date) {
        String paramValue = ParamCache.getValue("data_import_path");
        Path path = Paths.get(paramValue, date);
        TaskData result = conver2TaskData(path);

        DataFile sFile = result.getSFile();
        sFile.setLineSize(getFileLines(sFile.getPath()));
        DataFile dFile = result.getDFile();
        dFile.setLineSize(getFileLines(dFile.getPath()));

        return result;
    }

    /**
     * 获取所有已经导入过的数据
     * @author xsh
     * @date 2021/3/19 13:54
     * @param:
     * @return
     */
    public List<TaskData> getHasImportedTaskData() {
        PreImportValidate validate = new PreImportValidate();
        ValidateResult validateResult = validate.validateImportFolder();
        if(!validateResult.isPass()) {
            throw new ServiceException(validateResult.getMessage());
        }

        IImportRecordService recordService = SpringUtil.getBean(IImportRecordService.class);
        Set<String> runningDate = recordService.getAllRunningRecords().stream().map(ImportRecord::getDate).collect(Collectors.toSet());

        List<TaskData> result = getAllQualifiedDateFolder(validate)
                .stream()
                .filter(path -> !validate.validateDBTable(path.getFileName().toString()).isPass())
                .filter(path -> validate.validateDataFileName(path).isPass())
                .map(path -> conver2TaskData(path))
                .filter(taskData -> !runningDate.contains(taskData.getDate()))
                .collect(Collectors.toList());

        return result;
    }

    public List<TaskData> getCanImportedTaskData() {
        PreImportValidate validate = new PreImportValidate();
        ValidateResult validateResult = validate.validateImportFolder();
        if(!validateResult.isPass()) {
            throw new ServiceException(validateResult.getMessage());
        }

        List<TaskData> result = getAllQualifiedDateFolder(validate)
                .stream()
                .filter(path -> validate.validateDataFileName(path).isPass())
                .filter(path -> validate.validateDBTable(path.getFileName().toString()).isPass())
                .map(path -> conver2TaskData(path))
                .collect(Collectors.toList());

        return result;
    }



    private TaskData conver2TaskData(Path path) {
        String date = path.getFileName().toString();

        TaskData result = new TaskData();
        result.setDate(date);
        result.setTableName("region_data_"+date.replaceAll("-", "_"));

        result.setSFile(getDataFile(path, "sd_s_region.txt"));
        result.setDFile(getDataFile(path, "sd_d_region.txt"));

        return result;
    }

    private DataFile getDataFile(Path dateFolderPath, String suffix) {
        try {
            Path path = null;
            try (Stream<Path> pathStream = Files.list(dateFolderPath)){
                path = pathStream
                        .filter(item -> item.getFileName().toString().endsWith(suffix))
                        .findFirst()
                        .get();
            }

            DataFile result = new DataFile();
            result.setName(path.getFileName().toString());
            result.setPath(path.toString());
            result.setFileSize(Files.size(path));

            Date date = new Date(Files.getLastModifiedTime(path).toMillis());
            result.setLastModifiedTime(DateFormatUtils.format(date, "yyyy-MM-dd HH:mm:ss"));

            return result;
        } catch (IOException ioException) {
            ioException.printStackTrace();
        }
        return null;
    }

    /**
     * 获取所有合格的数据文件夹(文件夹名为yyyy-MM-dd)
     * @author xsh
     * @date 2021/3/19 13:58
     * @param:
     * @return
     * @param validate
     */
    private List<Path> getAllQualifiedDateFolder(PreImportValidate validate) {
        String importFolderPath = ParamCache.getValue("data_import_path");
        Path importFolder = Paths.get(importFolderPath);
        try {
            List<Path> result = Files
                    .list(importFolder)
                    .filter(path -> validate.validateDateFolderName(path.getFileName().toString()).isPass())
                    .collect(Collectors.toList());
            return result;
        } catch (IOException ioException) {
            return new ArrayList<>();
        }
    }

    private long getFileLines(String filePath) {

        try(FileReader in = new FileReader(filePath)) {
            LineNumberReader reader = new LineNumberReader(in);
            reader.skip(Long.MAX_VALUE);
            return reader.getLineNumber();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException ioException) {
            ioException.printStackTrace();
        }
        return 0;
    }



}
